home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume7 / flip < prev    next >
Encoding:
Text File  |  1989-07-08  |  51.5 KB  |  1,815 lines

  1. Newsgroups: comp.sources.misc
  2. From: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  3. Subject: v07i068: flip 1.0: a newline conversion program
  4. Reply-To: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
  5.  
  6. Posting-number: Volume 7, Issue 68
  7. Submitted-by: dhesi@bsu-cs.bsu.edu (Rahul Dhesi)
  8. Archive-name: flip
  9.  
  10. This program converts text file between MS-DOS and **IX format.  It
  11. works under System V, 4.3BSD, Ultrix, and MS-DOS/Turbo C.  It detects
  12. binary files in a nearly foolproof way and leaves them alone unless you
  13. override this.  It will also leave files alone that are already in the
  14. right format.  User interrupts are handled gracefully and no garbage or
  15. corrupted files left behind.  An MS-DOS binary will eventually appear
  16. in comp.binaries.ibm.pc.
  17.  
  18. Rahul Dhesi <dhesi@bsu-cs.bsu.edu>
  19. UUCP:    ...!{iuvax,pur-ee}!bsu-cs!dhesi
  20.  
  21. #! /bin/sh
  22. # This is a shell archive, meaning:
  23. # 1. Remove everything above the #! /bin/sh line.
  24. # 2. Save the resulting text in a file.
  25. # 3. Execute the file with /bin/sh (not csh) to create:
  26. #    Checksums
  27. #    FILES
  28. #    flip.1
  29. #    flip.c
  30. #    flip.h
  31. #    flip.man
  32. #    flip.prj
  33. #    getopt.c
  34. #    install.doc
  35. #    makefile.nix
  36. #    makefile.tcc
  37. #    turboc.c
  38. #    turboc.cfg
  39. # This archive created: Tue Jul  4 17:58:12 1989
  40. export PATH; PATH=/bin:/usr/bin:$PATH
  41. echo shar: "extracting 'Checksums'" '(429 characters)'
  42. if test -f 'Checksums'
  43. then
  44.     echo shar: "will not over-write existing file 'Checksums'"
  45. else
  46. sed 's/^X//' << \SHAR_EOF > 'Checksums'
  47. X# Whole file CRCs generated by Brik v1.0.  Use "brik -C" to verify them.
  48. X
  49. X# CRC-32        filename
  50. X# ------        --------
  51. X
  52. X2395754544      FILES
  53. X1324253258      flip.1
  54. X2015490080      flip.c
  55. X 116242883      flip.h
  56. X3654056916      flip.man
  57. X3390294771      flip.prj
  58. X2215166699      getopt.c
  59. X3196976162      install.doc
  60. X3441461244      makefile.nix
  61. X2236661872      makefile.tcc
  62. X3460687634      turboc.c
  63. X1182134946      turboc.cfg
  64. SHAR_EOF
  65. fi
  66. echo shar: "extracting 'FILES'" '(682 characters)'
  67. if test -f 'FILES'
  68. then
  69.     echo shar: "will not over-write existing file 'FILES'"
  70. else
  71. sed 's/^X//' << \SHAR_EOF > 'FILES'
  72. X  chars   name              description
  73. X
  74. X   3710   flip.1            (**ix) manual for formatting with "nroff -man"
  75. X   1731   makefile.nix      (**ix) make file 
  76. X
  77. X   4455   flip.man          (generic) formatted manual
  78. X   1522   install.doc       (generic) installation instructions
  79. X
  80. X  13273   flip.c            (generic) flip C source
  81. X   7556   flip.h            (generic) flip C source
  82. X   2801   getopt.c          (generic) getopt function C source
  83. X
  84. X    605   makefile.tcc      (ms-dos/turbo c) make file
  85. X     56   flip.prj          (ms-dos/turbo c) project file
  86. X    140   turboc.cfg        (ms-dos/turbo c) configuration file
  87. X  10224   turboc.c          (ms-dos/turbo c) C source
  88. SHAR_EOF
  89. fi
  90. echo shar: "extracting 'flip.1'" '(3710 characters)'
  91. if test -f 'flip.1'
  92. then
  93.     echo shar: "will not over-write existing file 'flip.1'"
  94. else
  95. sed 's/^X//' << \SHAR_EOF > 'flip.1'
  96. X.\" ::[[ @(#) flip.1 1.3 89/07/04 16:30:40 ::]]
  97. X.\"
  98. X.TH FLIP 1 "Jul 4, 1989"
  99. X.AT 3
  100. X.SH NAME
  101. Xflip \- do newline conversions between **IX and MS\-DOS
  102. X.SH SYNOPSIS
  103. X.B flip \-h
  104. X.sp  0
  105. X.B flip 
  106. X\-umvtsbz
  107. X.B file ...
  108. X.SH DESCRIPTION
  109. X.PP
  110. X.I Flip
  111. Xis a file interchange program that converts text file formats
  112. Xbetween **IX and MS\-DOS.  It converts lines ending with carriage\-return
  113. X(CR) and linefeed (LF) to lines ending with just linefeed, or vice versa.
  114. X.PP
  115. X.I Flip
  116. Xhas the following features.
  117. X.TP
  118. Xo
  119. XIf a file contains isolated CR characters for underlining or
  120. Xoverprinting,
  121. X.I flip
  122. Xdoes not change them.
  123. X.TP
  124. Xo
  125. XWhen asked to convert a file to the same format that it
  126. Xalready has,
  127. X.I flip
  128. Xcauses no change to the file.  Thus to
  129. Xconvert all files to **IX format you can type
  130. X.IP "" 10
  131. X.I flip
  132. X.B \-u
  133. X*.*  (under MS\-DOS)
  134. X.sp 0
  135. X.I flip
  136. X.B \-u
  137. X*    (under **IX)
  138. X.IP "" 5
  139. Xand all files will end up right, regardless of whether they
  140. Xwere in MS-DOS or in **IX format to begin with.  This also
  141. Xworks in the opposite direction.
  142. X.TP
  143. Xo
  144. X.I Flip
  145. Xpreserves file timestamps.  You can override this.
  146. X.TP
  147. Xo
  148. X.I Flip
  149. Xis written in C and will compile and run under
  150. XMS-DOS/Turbo C, 4.3BSD, and System V.
  151. X.TP
  152. Xo
  153. X.I Flip
  154. Xaccepts wildcards and multiple filenames on the
  155. Xcommand line.
  156. X.TP
  157. Xo
  158. XIf a user interrupt aborts
  159. X.IR Flip ,
  160. Xit does not leave behind
  161. Xany garbage files or cause corruption of the files being
  162. Xconverted.
  163. X.TP
  164. Xo
  165. X.I Flip
  166. Xwill normally refuse to convert binary files.  You can
  167. Xoverride this.
  168. X.TP
  169. Xo
  170. XWhen converting from MS-DOS to **IX format,
  171. X.I flip
  172. Xremoves any
  173. Xtrailing control Z (the last character in the file), but
  174. Xleaves embedded control Z characters unchanged.  This minimizes
  175. Xthe possibility of accidentally converting a binary file that
  176. Xcontains a control Z near the beginning.  You can override this
  177. Xand ask
  178. X.I flip
  179. Xto recognize the first control Z found as end-of-file.
  180. X.TP
  181. Xo
  182. X.I Flip
  183. Xcan be asked to strip the high (parity) bit as it converts
  184. Xa file.
  185. X.PP
  186. X.I Flip
  187. Xis normally invoked as:
  188. X.IP "" 5
  189. X.I flip
  190. X.B \-umhvtb
  191. Xfile ...
  192. X.IP "" 0
  193. XOne of
  194. X.BR \-u ,
  195. X.BR \-m ,
  196. Xor
  197. X.B \-h
  198. Xis required.  Switches may be given separately or
  199. Xcombined together after a dash.  For example, the three command lines given
  200. Xbelow are equivalent:
  201. X.IP "" 5
  202. X.I flip
  203. X.B \-uvt
  204. X*.c
  205. X.sp 0
  206. X.I flip
  207. X.B "-u -v -t"
  208. X*.c
  209. X.sp 0
  210. X.I flip
  211. X.B "-u -vt"
  212. X*.c
  213. X.PP
  214. XThe meanings of the switches are as follows.
  215. X.TP
  216. X\-u
  217. Xconvert to **IX format (CR LF => LF, lone CR or LF unchanged,
  218. Xtrailing control Z removed, embedded control Z unchanged)
  219. X.TP
  220. X\-m
  221. Xconvert to MS-DOS format (lone LF => CR LF, lone CR unchanged)
  222. X.TP
  223. X\-h
  224. Xgive a help message
  225. X.TP
  226. X\-v
  227. Xbe verbose, print filenames as they are processed
  228. X.TP
  229. X\-t
  230. Xtouch files (don't preserve timestamps)
  231. X.TP
  232. X\-s
  233. Xstrip high bit
  234. X.TP
  235. X\-b
  236. Xconvert binary files too (else binary files are left unchanged)
  237. X.TP
  238. X\-z
  239. Xtruncate file at first control Z encountered
  240. X.PP
  241. XOn systems that allow a program to know its own name,
  242. X.I flip
  243. Xmay be renamed (or
  244. Xlinked) to a file called
  245. X.I toix
  246. X(or
  247. X.I toix.exe
  248. Xunder MS-DOS) for conversion
  249. Xto **IX format, or to a file called
  250. X.I toms
  251. X(or
  252. X.I toms.exe
  253. Xunder MS-DOS) for
  254. Xconversion to MS-DOS format.  When invoked with the name
  255. X.I toix
  256. Xor
  257. X.IR toms,
  258. X.I flip
  259. Xwill act as if it were invoked with the
  260. X.B \-u
  261. Xor
  262. X.B \-m
  263. Xoption respectively.
  264. X.SH COPYRIGHT
  265. XBoth this documentation and
  266. X.I flip
  267. Xare Copyright 1989 Rahul Dhesi, all
  268. Xrights reserved.  Permission is granted to copy, use, and distribute for any
  269. Xcommercial or noncommercial purpose in accordance with the requirements of
  270. Xversion 1.0 of the
  271. X.I GNU General Public license.
  272. X.PP
  273. XNote:  This software has not been endorsed by the Free Software Foundation,
  274. Xthe creator of the GNU license, and I am not affiliated with that
  275. Xorganization.
  276. X.SH AUTHOR
  277. XRahul Dhesi
  278. SHAR_EOF
  279. fi
  280. echo shar: "extracting 'flip.c'" '(13273 characters)'
  281. if test -f 'flip.c'
  282. then
  283.     echo shar: "will not over-write existing file 'flip.c'"
  284. else
  285. sed 's/^X//' << \SHAR_EOF > 'flip.c'
  286. X/* ::[[ @(#) flip.c 1.18 89/07/04 16:07:16 ]]:: */
  287. X#ifndef LINT
  288. Xstatic char sccsid[]="::[[ @(#) flip.c 1.18 89/07/04 16:07:16 ]]::";
  289. X#endif
  290. X
  291. X/*
  292. XCopyright 1989 Rahul Dhesi, All rights reserved.
  293. X
  294. XChecksum: 1217582374 (check or update with "brik")
  295. X*/
  296. X
  297. X/*
  298. XDoes newline conversions between **IX and MS-DOS conventions.  Uses a state
  299. Xmachine, so repeated conversions on the same file will do no harm.
  300. XAssumes the US ASCII character set in some places (search for 'ASCII').
  301. X*/
  302. X
  303. X/* change contents of flip.h as needed */
  304. X#include "flip.h"
  305. X
  306. Xenum choices   { MSTOIX, IXTOMS, NEITHER };           /* conversion choices */
  307. Xenum state     { NONE, SAWCR, SAWLF, SAWCRLF, SAWCTRLZ };
  308. X
  309. Xvoid usage PARMS ((void));
  310. Xvoid give_help PARMS ((void));
  311. Xvoid flip_exit PARMS ((int));
  312. Xint getopt PARMS ((int argc, char **argv, char *options));
  313. Xvoid doarg PARMS ((char *, enum choices));
  314. Xint dofile PARMS ((char *, enum choices));
  315. Xchar *nextfile PARMS ((int, char *, int));
  316. Xint ixtoms PARMS ((FILE *, FILE *));
  317. Xint mstoix PARMS ((FILE *, FILE *));
  318. Xvoid error PARMS ((char *, char *));
  319. Xvoid setup_sigs PARMS ((void));
  320. Xvoid cleanup PARMS ((int));
  321. Xchar *mktemp PARMS ((char *));
  322. X
  323. X#ifdef STDINCLUDE
  324. X# include <stdlib.h>
  325. X# include <string.h>
  326. X#else
  327. Xvoid exit PARMS ((int));
  328. Xchar *strcpy PARMS ((char *, char *));
  329. X#endif
  330. X
  331. X#ifdef NDEBUG
  332. X# define assert(c)
  333. X#else
  334. X# ifdef STDINCLUDE
  335. X#  include <assert.h>
  336. X# else
  337. X#  define assert(c)  if(!(c)) \
  338. X                  fprintf(stderr,"assert error %s:%d\n",__FILE__,__LINE__)
  339. X# endif /* STDINCLUDE */
  340. X#endif /* NDEBUG */
  341. X
  342. X#ifdef USE_TABLE
  343. Xchar *bintab;
  344. X#endif
  345. X
  346. X#ifdef USE_SIG
  347. Xint got_sig;               /* will indicate if signal received */
  348. X#endif
  349. X
  350. Xchar *myname = NULL;
  351. X
  352. Xint exitstat = 0;          /* exit status */
  353. Xint verbose = 0;           /* set by -v option */
  354. Xint touch = 0;             /* set by -t option */
  355. Xint strip = 0;             /* set by -s option */
  356. Xint bintoo = 0;            /* set by -b option */
  357. Xint ztrunc = 0;            /* set by -z option */
  358. X
  359. Xmain (argc, argv)
  360. Xint argc;
  361. Xchar **argv;
  362. X
  363. X{
  364. X   int option;
  365. X   extern int optind;
  366. X   int i;
  367. X   enum choices which = NEITHER;
  368. X#ifdef USE_TABLE
  369. X#define TABSIZ    256
  370. X   char table[TABSIZ];
  371. X#endif
  372. X
  373. X#ifdef PICKNAME
  374. X   register char *p; /* temp pointer for finding our name */
  375. X   register char *arg0 = *argv;
  376. X#endif /* PICKNAME */
  377. X
  378. X   SPEC_INIT            /* optional initialization */
  379. X
  380. X#ifdef USE_SIG
  381. X   setup_sigs();
  382. X#endif
  383. X
  384. X#ifdef PICKNAME
  385. X# define STRCMP(a,op,b)    (strcmp(a,b) op 0)
  386. X   p = arg0 + strlen(arg0);
  387. X
  388. X   if (p != arg0) {     /* if program name is defined */
  389. X      while (p != arg0 && *p != '/' && *p != '\\')
  390. X         p--;
  391. X      assert ((p - arg0) <= strlen (arg0));
  392. X      if (p != arg0)
  393. X         p++;
  394. X
  395. X      /* p now points to trailing name component, or nothing */
  396. X      myname = p;
  397. X      while (*p != '\0' && *p != '.') {   /* ASCII convert to lowercase */
  398. X         if (*p >= 'A' && *p <= 'Z') {
  399. X            *p = (*p - 'A' + 'a');
  400. X         }
  401. X         p++;
  402. X      }
  403. X      if (p != myname && *p == '.')
  404. X         *p = '\0';     /* remove trailing .exe or .com under MS-DOS etc. */
  405. X
  406. X      if (STRCMP(myname,==,"toix"))
  407. X         which = MSTOIX;
  408. X      else if (STRCMP(myname,==,"toms"))
  409. X         which = IXTOMS;
  410. X   } else
  411. X   myname = "flip";
  412. X#else
  413. X   myname = "flip";
  414. X#endif /* PICKNAME */
  415. X
  416. Xargv[0] = myname;                /* for use by getopt */
  417. X
  418. X#ifdef USE_TABLE
  419. X/* table to find out which characters are binary */
  420. X   for (i = 0;  i < TABSIZ;  i++) {
  421. X      if ( (i < 7) || (i > 13 && i < 26) || (i > 126)) /*ASCII binary chars*/
  422. X         table[i] = 1;
  423. X      else
  424. X         table[i] = 0;
  425. X   }
  426. X   bintab = table;
  427. X#endif /* USE_TABLE */
  428. X
  429. X   if (argc < 2) {
  430. X      usage();
  431. X      flip_exit (1);
  432. X   }
  433. X
  434. X   while ((option = getopt (argc, argv, "umhvtsbz")) != EOF) {
  435. X      switch (option) {
  436. X       case 'u': which = MSTOIX;  break;
  437. X       case 'm': which = IXTOMS; break;
  438. X       case 'h': give_help(); flip_exit (0);
  439. X       case 'v': verbose = 1;  break;
  440. X       case 't': touch = 1;  break;
  441. X       case 's': strip = 1;  break;
  442. X       case 'b': bintoo = 1;  break;
  443. X       case 'z': ztrunc = 1;  break;
  444. X       default:  usage(); flip_exit (1);
  445. X      }
  446. X   }
  447. X
  448. X   switch (which) {
  449. X    case MSTOIX:
  450. X      /* printf ("converting to **ix format\n"); */
  451. X      break;
  452. X    case IXTOMS:
  453. X      /* printf ("converting to msdos format\n"); */
  454. X      break;
  455. X    default:
  456. X      fprintf (stderr, "%s: error: -u or -m is required\n", myname);
  457. X      flip_exit (1);
  458. X      break;
  459. X   }
  460. X
  461. X   if (argc <= optind) {
  462. X      fprintf (stderr, "%s: error: filenames are needed\n", myname);
  463. X      flip_exit (1);
  464. X   }
  465. X
  466. X   for (i = optind;  i < argc;  i++)
  467. X      doarg (argv[i], which);
  468. X
  469. X   return (exitstat);
  470. X}
  471. X
  472. X
  473. X/*
  474. XDoes conversion for one argument, calling dofile with wildcards
  475. Xexpanded.  Updates exitstat in case of error.
  476. X*/
  477. X
  478. Xvoid doarg (arg, which)
  479. Xchar *arg;
  480. Xenum choices which;
  481. X{
  482. X#ifdef WILDCARD
  483. X   char *this_file;
  484. X
  485. X   nextfile (0, arg, 0);
  486. X   while ((this_file = nextfile(1, (char *) NULL, 0)) != NULL) {
  487. X      exitstat |= dofile (this_file, which);
  488. X   }
  489. X#else
  490. X   exitstat |= dofile (arg, which);
  491. X#endif /* WILDCARD */
  492. X}
  493. X
  494. X#ifdef USE_SIG
  495. X# include <signal.h>
  496. X#endif
  497. X
  498. XFILE *outfile;       /* make it visible to both dofile and cleanup */
  499. X
  500. X/*
  501. XHere we have filename and an option.  We call a different routine
  502. Xfor each type of conversion.  This way more types of conversions
  503. Xcan be easily added in the future.
  504. X*/
  505. X
  506. Xint dofile (fname, which)
  507. Xchar *fname;
  508. Xenum choices which;
  509. X{
  510. X   FILE *infile;
  511. X   char tfname[PATHSIZE];
  512. X   SGFTIME timestamp;  /* save file timestamp here, restore later */
  513. X   int errstat = 0;
  514. X   char *p;             /* temp file ptr */
  515. X
  516. X#ifdef USE_SIG
  517. X   if (got_sig)
  518. X      flip_exit (INT_EXIT);
  519. X#endif
  520. X
  521. X   /* if writable, open for reading */
  522. X   if ((infile = fopen (fname, R_PL_B)) != NULL) {
  523. X      fclose (infile);
  524. X      infile = fopen (fname, RB);
  525. X   }
  526. X
  527. X   if (infile == NULL) {
  528. X      error (fname, ": can't open");
  529. X      return (1);
  530. X   }
  531. X
  532. X   /*
  533. X   to make temp file in same dir as original, we make p point to the filename
  534. X   component of fname, put '\0' there, and strcat the temp name to it
  535. X   */
  536. X   strcpy (tfname, fname);
  537. X   p = tfname + strlen(tfname);
  538. X
  539. X   while (p != tfname && *p != '/' && *p != '\\')
  540. X      p--;
  541. X   if (p != tfname)
  542. X      p++;
  543. X   *p = '\0';
  544. X
  545. X#define  TEMPLATE    "XXXXXX"
  546. X   {
  547. X      char template[7];
  548. X      strcpy (template, TEMPLATE);
  549. X      strcat (tfname, mktemp (template));
  550. X   }
  551. X
  552. X   outfile = fopen (tfname, WB);
  553. X
  554. X   if (outfile == NULL) {
  555. X      fclose (infile);
  556. X      error (fname, ": skipped, could not open temporary file");
  557. X      return (1);
  558. X   }
  559. X
  560. X   if (!touch)
  561. X      GETFT (infile, fname, timestamp);      /* save current timestamp */
  562. X
  563. X   assert (which == IXTOMS || which == MSTOIX);
  564. X
  565. X#ifdef BIGBUF
  566. X   setvbuf (infile,  (char *) NULL, _IOFBF, BIGBUF);
  567. X   setvbuf (outfile, (char *) NULL, _IOFBF, BIGBUF);
  568. X#endif /* BIGBUF */
  569. X
  570. X   switch (which) {
  571. X    case IXTOMS:
  572. X      errstat = ixtoms (infile, outfile);
  573. X      break;
  574. X    case MSTOIX:
  575. X      errstat = mstoix (infile, outfile);
  576. X      break;
  577. X   }
  578. X
  579. X   fclose (infile);
  580. X
  581. X   switch (errstat) {
  582. X    case ERRBINF:
  583. X      fclose (outfile);
  584. X      DELFILE (tfname);
  585. X      fprintf (stderr, "%s: binary file, not converted\n", fname);
  586. X      return (1);
  587. X      /* break; */  /* unreachable code */
  588. X#ifdef USE_SIG
  589. X    case ERRSIG:
  590. X      fclose (outfile);
  591. X      DELFILE (tfname);
  592. X      flip_exit (INT_EXIT);
  593. X      break;
  594. X#endif
  595. X    default:
  596. X      ;
  597. X   }
  598. X
  599. X   assert (errstat == 0);
  600. X
  601. X   if (!ferror(outfile) && fflush(outfile) != EOF && fclose(outfile) != EOF) {
  602. X      int moved;
  603. X      DELFILE (fname);
  604. X      moved = MVFILE (tfname, fname);
  605. X      if (moved == 0) {
  606. X         FILE *fptr;
  607. X         if (!touch && (fptr = fopen (fname, RB)) != NULL) {
  608. X            SETFT (fptr, fname, timestamp);
  609. X            fclose (fptr);
  610. X         }
  611. X         if (verbose) {
  612. X            printf ("%s\n", fname);
  613. X            fflush (stdout);
  614. X         }
  615. X         return (0);
  616. X      } else {
  617. X         error (fname, ": not converted, could not rename temp file");
  618. X         DELFILE (tfname);
  619. X         return (1);
  620. X      }
  621. X   } else {
  622. X      fclose (outfile); /* outfile was not closed, so close it here */
  623. X      return (1);
  624. X   }
  625. X}
  626. X
  627. X/* convert from ms-dos to **ix format */
  628. Xint mstoix (infile, outfile)
  629. XFILE *infile;           /* input file   */
  630. XFILE *outfile;          /* output file  */
  631. X{
  632. X   int c;
  633. X   enum state state = NONE;
  634. X
  635. X   /* lone LF => unchanged, lone CR => unchanged,
  636. X      CR LF => LF, ^Z at end means EOF; ^Z elsewhere => unchanged */
  637. X
  638. X   while (1) {       /* break out on EOF only */
  639. X      while ((c = getc (infile)) != EOF) {
  640. X#ifdef USE_SIG
  641. X         if (got_sig)
  642. X            return (ERRSIG);
  643. X#endif
  644. X         if (!bintoo && BINCHAR(c))
  645. X            return (ERRBINF);
  646. X         if (strip)
  647. X            STRIP(c);
  648. X         switch (c) {
  649. X          case LF:
  650. X            CHECK_BREAK
  651. X            putc (c, outfile); if (state == SAWCR) state = NONE; break;
  652. X          case CR:
  653. X            state = SAWCR; break;
  654. X          case CTRLZ:
  655. X            if (state == SAWCR) putc (CR, outfile);
  656. X            state = SAWCTRLZ; goto saweof;
  657. X          default:
  658. X            if (state == SAWCR) { state = NONE; putc (CR, outfile); }
  659. X            putc (c, outfile);
  660. X            break;
  661. X         }
  662. X      }
  663. X saweof:
  664. X      /* exit outer loop only on EOF or ^Z as last char */
  665. X      if (
  666. X          ztrunc && state == SAWCTRLZ
  667. X          || (c = getc (infile)) == EOF
  668. X         )
  669. X         break;
  670. X      else
  671. X         ungetc (c, infile);
  672. X      if (state == SAWCTRLZ)
  673. X         putc (CTRLZ, outfile);
  674. X   }
  675. X   return (0);
  676. X}
  677. X
  678. X/* convert from **ix to ms-dos format */
  679. Xint ixtoms (infile, outfile)
  680. XFILE *infile;           /* input file   */
  681. XFILE *outfile;          /* output file  */
  682. X{
  683. X   int c;
  684. X   enum state state = NONE;
  685. X
  686. X   /* LF => CR LF, but leave CR LF alone */
  687. X   while ((c = getc (infile)) != EOF) {
  688. X#ifdef USE_SIG
  689. X      if (got_sig)
  690. X         return (ERRSIG);
  691. X#endif
  692. X      if (!bintoo && BINCHAR(c))
  693. X         return (ERRBINF);
  694. X      if (strip)
  695. X         STRIP(c);
  696. X      switch (c) {
  697. X       case LF:
  698. X         CHECK_BREAK
  699. X         if (state == SAWCR)
  700. X            state = NONE;
  701. X         else
  702. X            putc (CR, outfile);
  703. X         putc (LF, outfile);
  704. X         break;
  705. X       case CR:
  706. X         state = SAWCR; putc (c, outfile); break;
  707. X       case CTRLZ:
  708. X         if (ztrunc)
  709. X            return (0);
  710. X         /* FALL THROUGH */
  711. X       default:
  712. X         state = NONE; putc (c, outfile); break;
  713. X      }
  714. X   }
  715. X   return (0);
  716. X}
  717. X
  718. X/* set up signal handler for selected signals */
  719. X#ifdef USE_SIG
  720. Xvoid setup_sigs ()
  721. X{
  722. X# ifdef SIGPIPE
  723. X   if (signal (SIGPIPE, SIG_IGN) != SIG_IGN)
  724. X      signal (SIGPIPE, cleanup);
  725. X# endif
  726. X# ifdef SIGHUP
  727. X   if (signal (SIGHUP, SIG_IGN) != SIG_IGN)
  728. X      signal (SIGHUP, cleanup);
  729. X# endif
  730. X# ifdef SIGQUIT
  731. X   if (signal (SIGQUIT, SIG_IGN) != SIG_IGN)
  732. X      signal (SIGQUIT, cleanup);
  733. X# endif
  734. X# ifdef SIGINT
  735. X   if (signal (SIGINT, SIG_IGN) != SIG_IGN)
  736. X      signal (SIGINT, cleanup);
  737. X# endif
  738. X# ifdef SIGTERM
  739. X   if (signal (SIGTERM, SIG_IGN) != SIG_IGN)
  740. X      signal (SIGTERM, cleanup);
  741. X# endif
  742. X}
  743. X
  744. X/* set flag on signal */
  745. Xvoid cleanup(sig)
  746. Xint sig;
  747. X{
  748. X   signal (sig, SIG_IGN);     /* needed for flaky System V Release 2 */
  749. X   got_sig = 1;
  750. X   signal (sig, cleanup);     /* ditto */
  751. X}
  752. X#endif /* USE_SIG */
  753. X
  754. X#define  ERRSIZE     200
  755. X
  756. X/* prints error message via perror */
  757. Xvoid error (msg1, msg2)
  758. Xchar *msg1, *msg2;
  759. X{
  760. X   char buf[ERRSIZE];
  761. X   strcpy (buf, myname);
  762. X   strcat (buf, ": ");
  763. X   strcat (buf, msg1);
  764. X   strcat (buf, msg2);
  765. X   perror (buf);
  766. X   fflush (stderr);
  767. X}
  768. X
  769. X/* gives brief usage message */
  770. Xvoid usage()
  771. X{
  772. X   fprintf (stderr,
  773. X"usage:  %s [-u | -m] [other options] file ...  (or \"%s -h\" for more help)\n",
  774. X myname, myname);
  775. X}
  776. X
  777. X/* gives help screen */
  778. X
  779. Xvoid give_help()
  780. X{
  781. Xprintf ("\
  782. XFile interchange program flip version 1.00.  Copyright 1989 Rahul Dhesi,\n\
  783. XAll rights reserved.  Both noncommercial and commercial copying, use, and\n\
  784. Xcreation of derivative works are permitted in accordance with the\n\
  785. Xrequirements of the GNU license.  This program does newline conversions.\n");
  786. X
  787. Xprintf ("\n\
  788. X   Usage:     flip -umhvtsbz file ...\n\
  789. X\n\
  790. XOne of -u, -m, or -h is required;  others are optional.  See user manual.\n");
  791. X
  792. Xprintf ("\n\
  793. X   -u     convert to **IX format (CR LF => LF, lone CR or LF unchanged,\n\
  794. X          trailing control Z removed, embedded control Z unchanged)\n\
  795. X   -m     convert to MS-DOS format (lone LF => CR LF, lone CR unchanged)\n\
  796. X   -h     give this help message\n\
  797. X   -v     be verbose, print filenames as they are processed\n\
  798. X   -t     touch files (don't preserve timestamps)\n\
  799. X   -s     strip high bit\n\
  800. X   -b     convert binary files too (else binary files are left unchanged)\n\
  801. X   -z     truncate file at first control Z encountered\n\
  802. X");
  803. X#ifdef PICKNAME
  804. Xprintf ("\n\
  805. XMay be invoked as \"toix\" (same as \"flip -u\") or \"toms\" (same as \"flip -m\").\n\
  806. X");
  807. X#endif
  808. Xreturn;
  809. X}
  810. X
  811. X/* normal exits go through here -- atexit would be nice but not portable */
  812. Xvoid flip_exit(stat)
  813. Xint stat;
  814. X{
  815. X   SPEC_EXIT
  816. X   exit (stat);
  817. X}
  818. X
  819. X/*
  820. Xspecial code for **IX -- not in use because can't properly handle
  821. XSIGINT while /bin/mv is executing
  822. X*/
  823. X
  824. X#ifdef NIX
  825. X# ifndef MVFILE
  826. Xint MVFILE (src, dest)
  827. Xchar *dest;
  828. Xchar *src;
  829. X{
  830. X   char cmd[2 * PATHSIZE];
  831. X   sprintf (cmd, "/bin/mv %s %s", src, dest);
  832. X   return (system(cmd));
  833. X}
  834. X# endif /* MVFILE */
  835. X#endif /* NIX */
  836. SHAR_EOF
  837. fi
  838. echo shar: "extracting 'flip.h'" '(7556 characters)'
  839. if test -f 'flip.h'
  840. then
  841.     echo shar: "will not over-write existing file 'flip.h'"
  842. else
  843. sed 's/^X//' << \SHAR_EOF > 'flip.h'
  844. X/* ::[[ @(#) flip.h 1.16 89/07/04 17:00:46 ]]:: */
  845. X
  846. X/*
  847. XCopyright 1989 Rahul Dhesi, All rights reserved.
  848. X
  849. XChecksum: 2652839101 (check or update with "brik")
  850. X
  851. XANSI-compatibility strategy:
  852. X
  853. X1.   If ANSIPROTO is defined, function prototypes are used, ANSI-style.
  854. X     If it is not defined, regular function declarations (without a
  855. X     parameter list) are used.  This is achieved with the use of
  856. X     the PARMS macro.
  857. X2.   If STDINCLUDE is defined, ANSI-conformant header files are
  858. X     included.  Otherwise functions that would be declared in such
  859. X     header files are declared individually.
  860. X*/
  861. X
  862. X#ifndef OK_NL
  863. X
  864. X/* Define ANSIPROTO and/or STDINCLUDE here if needed */
  865. X#ifdef TURBOC
  866. X# define    ANSIPROTO
  867. X# define    STDINCLUDE
  868. X#endif /* TURBOC */
  869. X
  870. X
  871. X
  872. X#include <stdio.h>
  873. X
  874. X#ifndef PARMS
  875. X# ifdef ANSIPROTO
  876. X#  define   PARMS(x)    x
  877. X# else
  878. X#  define   PARMS(x)    ()
  879. X# endif
  880. X#endif
  881. X
  882. X/************************************************************/
  883. X/*** change following definitions as needed for your system */
  884. X/************************************************************/
  885. X/*
  886. XBIGBUF      If defined, setvbuf() will be used to set input and
  887. X            output buffers to BIGBUF characters
  888. XBINCHAR     This must be a macro accepting a single character
  889. X            argument and returning nonzero if and only if that
  890. X            character is a binary character.  By default, BINCHAR
  891. X            is defined to look up a table, and the table is compiled
  892. X            in by defining USE_TABLE.
  893. XCHECK_BREAK If your operating system requires programs to check
  894. X            for user interrupts at intervals, define CHECK_BREAK to
  895. X            be a function or macro that checks for a user interrupt.
  896. X            Flip will call this at intervals.  If not needed,
  897. X            define CHECK_BREAK to be null.
  898. XDELFILE     Must be a function or macro that will accept one filenames
  899. X            and delete that file, returning zero on success, nonzero
  900. X            on failure.
  901. XGETFT       Must be a macro with usage GETFT(file,name,var) that will
  902. X            take an open file, a filename, and a variable name, and
  903. X            put in that variable the timestamp of the file.
  904. XINT_EXIT    If USE_SIG is defined, INT_EXIT must be defined to
  905. X            be the exit code returned by flip when its execution
  906. X            is aborted by a user interrupt.
  907. XMVFILE      Must be a function or macro that will take two filenames
  908. X            and rename the first file to the second file, returning
  909. X            zero on success, nonzero on failure.
  910. XNIX         If this symbol is defined, some things common to most
  911. X            implementations of **IX get defined and need not be
  912. X            individually defined.
  913. XPATHSIZE    size of buffer(s) to use to hold pathname(s)
  914. XPICKNAME    Do "#define PICKNAME" if you want the program to know its
  915. X            name and respond to it.  If PICKNAME is not defined, the
  916. X            program will assume that it is called "flip".
  917. XSETFT       Must be a function or macro with usage SETFT(file,name,var)
  918. X            that will take an open file, a filename, and a variable
  919. X            name, and set the timestamp of the file from the variable.
  920. XSIG_T       If USE_SIG is defined, then SIG_T must be defined
  921. X            (or typedef'd) to be the data type returned by
  922. X            (*signal).  Usually int or void.
  923. XSPEC_EXIT   Like SPEC_INIT, but is called just before flip exits.
  924. XSPEC_INIT   This is invoked to initialize flip.  Should be defined to
  925. X            be either a function call (with trailing semicolon) or
  926. X            null string.
  927. XSGFTIME     This must be a typedef for a data type suitable to store
  928. X            file times.
  929. XUSE_TABLE   If this is defined, flip code will use a table look-up
  930. X            to decide which characters should be considered binary.
  931. X            See also BINCHAR.
  932. XULTRIX_BUG  At least one version of Ultrix chokes on a trailing "b"
  933. X            in the mode string for fopen().  If ULTRIX_BUG is defined
  934. X            no trailing "b" will be used.
  935. XUSE_SIG     If this is defined, then signal() will be used so flip
  936. X            may trap user interrupts and delete temporary files.
  937. X            If USE_SIG is defined, then SIG_T and INT_EXIT must also
  938. X            be defined (below).
  939. XWILDCARD    If this is defined, the function nextfile() will be called
  940. X            to expand wildcards.  If WILDCARD is not defined, no
  941. X            wildcard expansion will be done and nextfile() is not
  942. X            needed.  For a description of nextfile() see turboc.c.
  943. X*/
  944. X
  945. X#ifdef TURBOC
  946. X# define PATHSIZE    200
  947. X# define PICKNAME
  948. X# define BIGBUF      16384
  949. X# define DELFILE     remove
  950. Xextern int MVFILE PARMS ((char *src, char *dest));            /* Turbo C */
  951. X# define USE_SIG
  952. X# define SIG_T void     /* return type from (*signal) */
  953. X# define INT_EXIT 127   /* status when a signal causes exit */
  954. X# define CHECK_BREAK  brktst();
  955. Xvoid brktst PARMS ((void));
  956. X# define SPEC_INIT   spec_init();
  957. X# define SPEC_EXIT   spec_exit();
  958. Xvoid spec_init PARMS ((void));
  959. Xvoid spec_exit PARMS ((void));
  960. X# define WILDCARD
  961. X
  962. X/* date and time */
  963. X# include <io.h>
  964. X  typedef struct ftime        SGFTIME;
  965. X# define GETFT(f,name,var)    getftime(fileno(f), &var)
  966. X# define SETFT(f,name,var)    setftime(fileno(f), &var)
  967. X#endif /* TURBOC */
  968. X
  969. X#ifdef SYS_V
  970. X# define NIX         /* see below */
  971. X# define PATHSIZE    200
  972. X# define BIGBUF      16384
  973. X# define  MVFILE(src,dest)    (!(!link(src,dest)&&!unlink(src)))
  974. X# define SIG_T int
  975. X#endif /* SYS_V */
  976. X
  977. X#ifdef BSD
  978. X# define NIX         /* see below */
  979. X# define PATHSIZE    1027
  980. X# undef  BIGBUF
  981. X# define  MVFILE     rename
  982. X# define SIG_T int
  983. X#endif /* BSD */
  984. X
  985. X#ifdef VMS
  986. X# define PATHSIZE    1024
  987. X# define PICKNAME
  988. X# define BIGBUF      16384
  989. X# define DELFILE     delete
  990. X# define  MVFILE     rename
  991. X# define USE_SIG
  992. X# define SIG_T int
  993. X# define INT_EXIT    127
  994. X# define SPEC_INIT
  995. X# define SPEC_EXIT
  996. X#endif /* VMS */
  997. X
  998. X/************************************************************/
  999. X/*** remaining definitions should not need to be changed ****/
  1000. X/************************************************************/
  1001. X
  1002. X/* define ASCII character values for linefeed, carriage return, control Z */
  1003. X#define  LF    10
  1004. X#define  CR    13
  1005. X#define  CTRLZ 26
  1006. X
  1007. X/* error codes */
  1008. X#define  ERRBINF  1  /* binary file */
  1009. X#define  ERRSIG   2  /* interrupted by signal */
  1010. X
  1011. X/* how to strip high bit */
  1012. X#define  STRIP(c)    c &= 0x7f
  1013. X
  1014. X/**** BINCHAR(c) returns nonzero if c is a binary char ****/
  1015. X#ifndef BINCHAR
  1016. X# define USE_TABLE      /* use internal table -- see flip.c */
  1017. X# define BINCHAR(c)  bintab[c]
  1018. X#endif
  1019. X
  1020. X/**** mode strings for fopen() -- to work around Ultrix problem ****/
  1021. X/**** (Thanks to Taso N. Devetzis for reporting this)           ****/
  1022. X#ifdef ULTRIX_BUG
  1023. X# define WB          "w"
  1024. X# define RB          "r"
  1025. X# define R_PL_B      "r+"
  1026. X#else
  1027. X# define WB          "wb"     /* write binary */
  1028. X# define RB          "rb"     /* read binary */
  1029. X# define R_PL_B      "r+b"    /* read + update binary */
  1030. X#endif /* ULTRIX_BUG */
  1031. X
  1032. X/* things common to most **IX systems */
  1033. X#ifdef NIX
  1034. X# define SPEC_INIT
  1035. X# define SPEC_EXIT
  1036. X# define CHECK_BREAK
  1037. X# define PICKNAME
  1038. X# define DELFILE     unlink
  1039. X# define USE_SIG
  1040. X# define INT_EXIT    127
  1041. X# include <sys/types.h>          /* for file time */
  1042. X# include <sys/stat.h>           /* for file time */
  1043. X  typedef struct stat            SGFTIME;
  1044. X# define GETFT(file,name,var)    fstat(fileno(file),&var)
  1045. X# define SETFT(file,name,var)    do { time_t x[2]; x[0] = var.st_atime; \
  1046. X                                      x[1] = var.st_mtime; utime (name, x); \
  1047. X                                  } while (0)
  1048. X#endif /* NIX */
  1049. X
  1050. X#endif /* OK_NL */
  1051. SHAR_EOF
  1052. fi
  1053. echo shar: "extracting 'flip.man'" '(4455 characters)'
  1054. if test -f 'flip.man'
  1055. then
  1056.     echo shar: "will not over-write existing file 'flip.man'"
  1057. else
  1058. sed 's/^X//' << \SHAR_EOF > 'flip.man'
  1059. X
  1060. X     FLIP(1)                  REFERENCE MANUAL              FLIP(1)
  1061. X
  1062. X
  1063. X     NAME
  1064. X          flip - do newline conversions between **IX and MS-DOS
  1065. X
  1066. X     SYNOPSIS
  1067. X          flip -h
  1068. X          flip -umvtsbz file ...
  1069. X
  1070. X     DESCRIPTION
  1071. X          Flip is a file interchange program that converts text file
  1072. X          formats between **IX and MS-DOS.  It converts lines ending
  1073. X          with carriage-return (CR) and linefeed (LF) to lines ending
  1074. X          with just linefeed, or vice versa.
  1075. X
  1076. X          Flip has the following features.
  1077. X
  1078. X          o    If a file contains isolated CR characters for
  1079. X               underlining or overprinting, flip does not change them.
  1080. X
  1081. X          o    When asked to convert a file to the same format that it
  1082. X               already has, flip causes no change to the file.  Thus
  1083. X               to convert all files to **IX format you can type
  1084. X
  1085. X                    flip -u *.*  (under MS-DOS)
  1086. X                    flip -u *    (under **IX)
  1087. X
  1088. X               and all files will end up right, regardless of whether
  1089. X               they were in MS-DOS or in **IX format to begin with.
  1090. X               This also works in the opposite direction.
  1091. X
  1092. X          o    Flip preserves file timestamps.  You can override this.
  1093. X
  1094. X          o    Flip is written in C and will compile and run under
  1095. X               MS-DOS/Turbo C, 4.3BSD, and System V.
  1096. X
  1097. X          o    Flip accepts wildcards and multiple filenames on the
  1098. X               command line.
  1099. X
  1100. X          o    If a user interrupt aborts Flip, it does not leave
  1101. X               behind any garbage files or cause corruption of the
  1102. X               files being converted.
  1103. X
  1104. X          o    Flip will normally refuse to convert binary files.  You
  1105. X               can override this.
  1106. X
  1107. X          o    When converting from MS-DOS to **IX format, flip
  1108. X               removes any trailing control Z (the last character in
  1109. X               the file), but leaves embedded control Z characters
  1110. X               unchanged.  This minimizes the possibility of
  1111. X               accidentally converting a binary file that contains a
  1112. X               control Z near the beginning.  You can override this
  1113. X               and ask flip to recognize the first control Z found as
  1114. X               end-of-file.
  1115. X
  1116. X          o    Flip can be asked to strip the high (parity) bit as it
  1117. X               converts a file.
  1118. X
  1119. X          Flip is normally invoked as:
  1120. X
  1121. X               flip -umhvtb file ...
  1122. X
  1123. X          One of -u, -m, or -h is required.  Switches may be given
  1124. X          separately or combined together after a dash.  For example,
  1125. X          the three command lines given below are equivalent:
  1126. X
  1127. X               flip -uvt *.c
  1128. X               flip -u -v -t *.c
  1129. X               flip -u -vt *.c
  1130. X
  1131. X          The meanings of the switches are as follows.
  1132. X
  1133. X          -u   convert to **IX format (CR LF => LF, lone CR or LF
  1134. X               unchanged, trailing control Z removed, embedded control
  1135. X               Z unchanged)
  1136. X
  1137. X          -m   convert to MS-DOS format (lone LF => CR LF, lone CR
  1138. X               unchanged)
  1139. X
  1140. X          -h   give a help message
  1141. X
  1142. X          -v   be verbose, print filenames as they are processed
  1143. X
  1144. X          -t   touch files (don't preserve timestamps)
  1145. X
  1146. X          -s   strip high bit
  1147. X
  1148. X          -b   convert binary files too (else binary files are left
  1149. X               unchanged)
  1150. X
  1151. X          -z   truncate file at first control Z encountered
  1152. X
  1153. X          On systems that allow a program to know its own name, flip
  1154. X          may be renamed (or linked) to a file called toix (or
  1155. X          toix.exe under MS-DOS) for conversion to **IX format, or to
  1156. X          a file called toms (or toms.exe under MS-DOS) for conversion
  1157. X          to MS-DOS format.  When invoked with the name toix or toms,
  1158. X          flip will act as if it were invoked with the -u or -m option
  1159. X          respectively.
  1160. X
  1161. X     COPYRIGHT
  1162. X          Both this documentation and flip are Copyright 1989 Rahul
  1163. X          Dhesi, all rights reserved.  Permission is granted to copy,
  1164. X          use, and distribute for any commercial or noncommercial
  1165. X          purpose in accordance with the requirements of version 1.0
  1166. X          of the GNU General Public license.
  1167. X
  1168. X          Note:  This software has not been endorsed by the Free
  1169. X          Software Foundation, the creator of the GNU license, and I
  1170. X          am not affiliated with that organization.
  1171. X
  1172. X     AUTHOR
  1173. X          Rahul Dhesi
  1174. X
  1175. X     DATE
  1176. X          This manual was formatted 1989/04/07.  It is for version
  1177. X          1.00 of flip.
  1178. SHAR_EOF
  1179. fi
  1180. echo shar: "extracting 'flip.prj'" '(56 characters)'
  1181. if test -f 'flip.prj'
  1182. then
  1183.     echo shar: "will not over-write existing file 'flip.prj'"
  1184. else
  1185. sed 's/^X//' << \SHAR_EOF > 'flip.prj'
  1186. Xflip.c            (flip.h)
  1187. Xgetopt.c        (flip.h)
  1188. Xturboc.c        (flip.h)
  1189. SHAR_EOF
  1190. fi
  1191. echo shar: "extracting 'getopt.c'" '(2801 characters)'
  1192. if test -f 'getopt.c'
  1193. then
  1194.     echo shar: "will not over-write existing file 'getopt.c'"
  1195. else
  1196. sed 's/^X//' << \SHAR_EOF > 'getopt.c'
  1197. X/* ::[[ @(#) getopt.c 1.5 89/07/02 00:18:19 ]]:: */
  1198. X#ifndef LINT
  1199. Xstatic char sccsid[]="::[[ @(#) getopt.c 1.5 89/07/02 00:18:19 ]]::";
  1200. X#endif
  1201. X
  1202. X/*
  1203. XChecksum:  505161377      (check or update this with "brik")
  1204. X*/
  1205. X
  1206. X/*
  1207. X * Here's something you've all been waiting for:  the AT&T public domain
  1208. X * source for getopt(3).  It is the code which was given out at the 1985
  1209. X * UNIFORUM conference in Dallas.  I obtained it by electronic mail
  1210. X * directly from AT&T.  The people there assure me that it is indeed
  1211. X * in the public domain.
  1212. X *
  1213. X * There is no manual page.  That is because the one they gave out at
  1214. X * UNIFORUM was slightly different from the current System V Release 2
  1215. X * manual page.  The difference apparently involved a note about the
  1216. X * famous rules 5 and 6, recommending using white space between an option
  1217. X * and its first argument, and not grouping options that have arguments.
  1218. X * Getopt itself is currently lenient about both of these things White
  1219. X * space is allowed, but not mandatory, and the last option in a group can
  1220. X * have an argument.  That particular version of the man page evidently
  1221. X * has no official existence, and my source at AT&T did not send a copy.
  1222. X * The current SVR2 man page reflects the actual behavor of this getopt.
  1223. X * However, I am not about to post a copy of anything licensed by AT&T.
  1224. X */
  1225. X
  1226. X/*
  1227. XMinor modifications by Rahul Dhesi 1989/03/06
  1228. X*/
  1229. X
  1230. X#include "flip.h"
  1231. X
  1232. X#ifdef STDINCLUDE
  1233. X# include <string.h>
  1234. X#else
  1235. Xextern int strcmp PARMS ((char *, char *));
  1236. Xextern char *strchr PARMS ((char *, char));
  1237. X#endif
  1238. X
  1239. X/* Avoid possible compiler warning if we simply redefine NULL or EOF */
  1240. X#define XNULL   0
  1241. X#define XEOF (-1)
  1242. X
  1243. X#define ERR(szz,czz) if(opterr){fprintf(stderr,"%s%s%c\n",argv[0],szz,czz);}
  1244. X
  1245. Xint   opterr = 1;
  1246. Xint   optind = 1;
  1247. Xint   optopt;
  1248. Xchar  *optarg;
  1249. X
  1250. Xint
  1251. Xgetopt(argc, argv, opts)
  1252. Xint   argc;
  1253. Xchar  **argv, *opts;
  1254. X{
  1255. X   static int sp = 1;
  1256. X   register int c;
  1257. X   register char *cp;
  1258. X
  1259. X   if(sp == 1)
  1260. X      if(optind >= argc ||
  1261. X         argv[optind][0] != '-' || argv[optind][1] == '\0')
  1262. X         return(XEOF);
  1263. X      else if(strcmp(argv[optind], "--") == XNULL) {
  1264. X         optind++;
  1265. X         return(XEOF);
  1266. X      }
  1267. X   optopt = c = argv[optind][sp];
  1268. X   if(c == ':' || (cp=strchr(opts, c)) == XNULL) {
  1269. X      ERR(": illegal option -- ", c);
  1270. X      if(argv[optind][++sp] == '\0') {
  1271. X         optind++;
  1272. X         sp = 1;
  1273. X      }
  1274. X      return('?');
  1275. X   }
  1276. X   if(*++cp == ':') {
  1277. X      if(argv[optind][sp+1] != '\0')
  1278. X         optarg = &argv[optind++][sp+1];
  1279. X      else if(++optind >= argc) {
  1280. X         ERR(": option requires an argument -- ", c);
  1281. X         sp = 1;
  1282. X         return('?');
  1283. X      } else
  1284. X         optarg = argv[optind++];
  1285. X      sp = 1;
  1286. X   } else {
  1287. X      if(argv[optind][++sp] == '\0') {
  1288. X         sp = 1;
  1289. X         optind++;
  1290. X      }
  1291. X      optarg = XNULL;
  1292. X   }
  1293. X   return(c);
  1294. X}
  1295. SHAR_EOF
  1296. fi
  1297. echo shar: "extracting 'install.doc'" '(1522 characters)'
  1298. if test -f 'install.doc'
  1299. then
  1300.     echo shar: "will not over-write existing file 'install.doc'"
  1301. else
  1302. sed 's/^X//' << \SHAR_EOF > 'install.doc'
  1303. X
  1304. X                             Installing Flip 1.00
  1305. X
  1306. XInstallation instructions are provided for System V Release 2, 4.3BSD,
  1307. XUltrix, Microport System V/AT, and MS-DOS/Turbo C.  To install under other
  1308. Xsimilar environments look carefully in flip.h and make changes as needed.
  1309. X
  1310. X
  1311. XMS-DOS/TURBO C
  1312. X
  1313. XThe files supplied are suitable for compilation with Borland's Turbo C 2.0
  1314. Xfor MS-DOS.
  1315. X
  1316. XA makefile "makefile.tcc" is supplied.  Use the command line compiler
  1317. X"tcc.exe".  You will need a good make program, such as NDMAKE.  Edit
  1318. X"turboc.cfg" so it correctly reflects the include directories on your
  1319. Xsystem.  Then type "make -f makefile.tcc".
  1320. X
  1321. XYou can also use the intergrated environment "tc.exe".  Convert "turboc.cfg"
  1322. Xto "tcconfig.tc" using Borland's "tcconfig.exe" program.  Invoke tc.exe and
  1323. Xload the configuration file "tcconfig.tc".  A project file "flip.prj" is
  1324. Xsupplied.  Compile as usual.
  1325. X
  1326. X
  1327. XSYSTEM V RELEASE 2, 4.3BSD, OR MICROPORT SYSTEM V/AT
  1328. X
  1329. XRename the provided file "makefile.nix" to "makefile".
  1330. X
  1331. XDepending on the system, type:
  1332. X
  1333. X     make sys_v                 for System V Release 2
  1334. X     make bsd                   for 4.3BSD
  1335. X     make uport                 for Microport System V/AT (large model)
  1336. X     make ultrix                for Ultrix, includes bug fix, not tested
  1337. X
  1338. XIt may work to do "make sys_v" for Microport System V/AT, but I'm not sure,
  1339. Xas I haven't yet restored my small model libraries which vanished from my
  1340. Xdisk one day without warning.
  1341. X
  1342. XUnder any flavor of **IX you can link "flip" to "toix" and "toms".
  1343. SHAR_EOF
  1344. fi
  1345. echo shar: "extracting 'makefile.nix'" '(1731 characters)'
  1346. if test -f 'makefile.nix'
  1347. then
  1348.     echo shar: "will not over-write existing file 'makefile.nix'"
  1349. else
  1350. sed 's/^X//' << \SHAR_EOF > 'makefile.nix'
  1351. X# Makefile for flip for **IX.  ::[[ @(#) makefile.nix 1.4 89/07/04 12:00:02 ]]::
  1352. X
  1353. X# The contents of this makefile are hereby released to the public domain.
  1354. X#                               -- Rahul Dhesi 1989/06/19
  1355. X
  1356. X# Before use make sure this file is called "makefile".  (Rename it if
  1357. X# necessary.)  Then invoke as follows:
  1358. X
  1359. X#   "make sys_v"        makes executable flip for System V Release 2
  1360. X#   "make bsd"          makes executable flip for 4.3BSD
  1361. X#   "make install"      moves flip into BINDIR, copies flip.1 into MANDIR
  1362. X#   "make clean"        deletes object and executable files
  1363. X
  1364. X# Where to install executable and manual files on "make install".  The trailing
  1365. X# "/." forces an error message if the destination directory doesn't exist.
  1366. XBINDIR = /usr/local/bin/.
  1367. XMANDIR = /usr/man/man1/.
  1368. X
  1369. X# CC is compiler, LD is loader (may be same as compiler), CFLAGS are flags
  1370. X# for compiler, LDFLAGS are flags for loader, CFMORE are additional
  1371. X# (relatively unchanging) flags for compiler
  1372. X
  1373. XCC = cc
  1374. XCFLAGS =
  1375. XCFMORE = -c -DNDEBUG -O
  1376. XLD = cc
  1377. XLDFLAGS = -o flip
  1378. X
  1379. X# If your system does not supply getopt as a library function,
  1380. X# add getopt.o to the RHS list on the next line and uncomment the
  1381. X# two nonblank lines after that.
  1382. XOBJS = flip.o
  1383. X
  1384. X#getopt.o: getopt.c flip.h
  1385. X#    $(CC) $(CFLAGS) $(CFMORE) $*.c
  1386. X
  1387. Xnothing:
  1388. X    @echo \
  1389. X    'Please type "make sys_v", "make bsd", "make uport", or "make ultrix"'
  1390. X
  1391. Xsys_v:
  1392. X    make "CFLAGS=-DSYS_V" flip
  1393. X
  1394. Xuport:
  1395. X    make "CFLAGS=-DSYS_V -Ml" "LDFLAGS=-Ml -o flip" flip
  1396. X
  1397. Xbsd:
  1398. X    make "CFLAGS=-DBSD" flip
  1399. X
  1400. Xultrix:
  1401. X    make "CFLAGS=-DBSD -DULTRIX_BUG" flip
  1402. X
  1403. Xflip: $(OBJS)
  1404. X    $(LD) $(LDFLAGS) $(OBJS)
  1405. X
  1406. Xflip.o: flip.c flip.h
  1407. X    $(CC) $(CFLAGS) $(CFMORE) $*.c
  1408. X
  1409. Xclean:
  1410. X    rm -f *.o core flip
  1411. X
  1412. Xinstall:
  1413. X    mv flip $(BINDIR)
  1414. X    cp flip.1 $(MANDIR)
  1415. SHAR_EOF
  1416. fi
  1417. echo shar: "extracting 'makefile.tcc'" '(605 characters)'
  1418. if test -f 'makefile.tcc'
  1419. then
  1420.     echo shar: "will not over-write existing file 'makefile.tcc'"
  1421. else
  1422. sed 's/^X//' << \SHAR_EOF > 'makefile.tcc'
  1423. X# ::[[ @(#) makefile.tcc 1.1 89/07/02 00:19:54 ]]::
  1424. X# Makefile for flip for MS-DOS and Turbo C 2.0.  The supplied turboc.cfg
  1425. X# configuration file must be in the current directory;  edit it to make
  1426. X# sure the include directories are correct.
  1427. X
  1428. XCC = tcc
  1429. XCFLAGS = -c -DTURBOC -DLINT -DNDEBUG
  1430. XCFMORE =
  1431. XLD = tcc
  1432. XLDFLAGS = -eFLIP
  1433. XLDMORE =
  1434. X
  1435. XOBJS = flip.obj getopt.obj turboc.obj
  1436. X
  1437. Xflip.exe: $(OBJS)
  1438. X    $(LD) $(LDFLAGS) $(LDMORE) $(OBJS)
  1439. X
  1440. Xflip.obj: flip.c flip.h
  1441. X    $(CC) $(CFLAGS) $(CFMORE) $*.c
  1442. X
  1443. Xgetopt.obj: getopt.c flip.h
  1444. X    $(CC) $(CFLAGS) $(CFMORE) $*.c
  1445. X
  1446. Xturboc.obj: turboc.c flip.h
  1447. X    $(CC) $(CFLAGS) $(CFMORE) $*.c
  1448. SHAR_EOF
  1449. fi
  1450. echo shar: "extracting 'turboc.c'" '(10224 characters)'
  1451. if test -f 'turboc.c'
  1452. then
  1453.     echo shar: "will not over-write existing file 'turboc.c'"
  1454. else
  1455. sed 's/^X//' << \SHAR_EOF > 'turboc.c'
  1456. X/* ::[[ @(#) turboc.c 1.6 89/07/02 00:19:31 ]]:: */
  1457. X#ifndef LINT
  1458. Xstatic char sccsid[]="::[[ @(#) turboc.c 1.6 89/07/02 00:19:31 ]]::";
  1459. X#endif
  1460. X
  1461. X/*
  1462. XCopyright 1989 Rahul Dhesi, All rights reserved.
  1463. X
  1464. XThis file is used only for MS-DOS & Turbo C.
  1465. X*/
  1466. X
  1467. X/*
  1468. XChecksum: 3933529970      (check or update this with "brik")
  1469. X*/
  1470. X
  1471. X/*
  1472. Xnextfile() is a general wildcard expansion function that may be used
  1473. Xwith other programs.  Usage instructions are below.  It does not
  1474. Xsimply expand wildcards in an entire argument list.  Instead, it is
  1475. Xcalled in a loop as described below, and returns one matching
  1476. Xfilename each time it is called.
  1477. X
  1478. XThese functions are for the SMALL MEMORY MODEL ONLY.
  1479. X*/
  1480. X
  1481. Xextern unsigned _stklen = 10000;
  1482. X
  1483. X#include "assert.h"
  1484. X#include "flip.h"
  1485. X
  1486. X#define  FMAX  2        /* Number of different filename patterns */
  1487. X#define  PATHSIZE 200   /* Size of MS-DOS pathname */
  1488. X#define  NULL  0
  1489. X
  1490. X#ifdef ANSIPROTO
  1491. Xchar *strtcpy (char *, char *);
  1492. Xint strlen (char *);
  1493. Xchar *strcpy (char *, char *);
  1494. X#endif
  1495. X
  1496. X
  1497. X/* Structure definitions for MS-DOS software interrupt intdos() */
  1498. X
  1499. Xstruct WORD_REGISTERS {
  1500. X   unsigned int ax, bx, cx, dx, si, di, carry, flags;
  1501. X};
  1502. X
  1503. X/* byte registers */
  1504. X
  1505. Xstruct BYTE_REGISTERS {
  1506. X   unsigned char al, ah, bl, bh, cl, ch, dl, dh;
  1507. X};
  1508. X
  1509. Xunion REGS {
  1510. X   struct WORD_REGISTERS x;
  1511. X   struct BYTE_REGISTERS h;
  1512. X};
  1513. X
  1514. Xint intdos (union REGS *, union REGS *);
  1515. X
  1516. X/*
  1517. Xformat of disk transfer address after MS-DOS calls FindFirst and
  1518. XFindNext
  1519. X*/
  1520. Xstruct dta_t {
  1521. X   char junk[22];
  1522. X   int time;
  1523. X   int date;
  1524. X   long size;
  1525. X   char fname[13];
  1526. X   char just_in_case[4];   /* in case MS-DOS writes too much */
  1527. X};
  1528. X
  1529. Xvoid setdta (struct dta_t *);
  1530. Xvoid fcbpath (struct dta_t *, char *, char *);
  1531. X
  1532. X/*******************/
  1533. X/*
  1534. Xnextfile() returns the name of the next source file matching a filespec.
  1535. X
  1536. XINPUT
  1537. X   what: A flag specifying what to do.  If "what" is 0, nextfile()
  1538. X      initializes itself.  If "what" is 1, nextfile() returns the next
  1539. X      matching filename.
  1540. X   filespec:  The filespec, usually containing wildcard characters, that
  1541. X      specifies which files are needed.  If "what" is 0, filespec must be
  1542. X      the filespec for which matching filenames are needed.  If "what" is 1,
  1543. X      nextfile() does not use "filespec" and "filespec" should be NULL to
  1544. X      avoid an assertion error during debugging.
  1545. X   fileset:  nextfile() can keep track of more than one set of filespecs.
  1546. X      The fileset specifies which filespec is being matched and therefore
  1547. X      which set of files is being considered.  "fileset" can be in the
  1548. X      range 0:FMAX.  Initialization of one fileset does not affect the
  1549. X      other filesets.
  1550. X
  1551. XOUTPUT
  1552. X   IF what == 0 THEN
  1553. X      return value is NULL
  1554. X   ELSE IF what == 1 THEN
  1555. X      IF a matching filename is found THEN
  1556. X         return value is pointer to matching filename including supplied path
  1557. X      ELSE
  1558. X         IF at least one file matched previously but no more match THEN
  1559. X            return value is NULL
  1560. X         ELSE IF supplied filespec never matched any filename THEN
  1561. X            IF this is the first call with what == 1 THEN
  1562. X               return value is pointer to original filespec
  1563. X            ELSE
  1564. X               return value is NULL
  1565. X            END IF
  1566. X         END IF
  1567. X      END IF
  1568. X   END IF
  1569. X
  1570. XNOTE
  1571. X
  1572. X   Initialization done when "what"=0 is not dependent on the correctness
  1573. X   of the supplied filespec but simply initializes internal variables
  1574. X   and makes a local copy of the supplied filespec.  If the supplied
  1575. X   filespec was illegal, the only effect is that the first time that
  1576. X   nextfile() is called with "what"=1, it will return the original
  1577. X   filespec instead of a matching filename.  That the filespec was
  1578. X   illegal will become obvious when the caller attempts to open the
  1579. X   returned filename for input/output and the open attempt fails.
  1580. X
  1581. XUSAGE HINTS
  1582. X
  1583. Xnextfile() can be used in the following manner:
  1584. X
  1585. X      char *filespec;                  -- will point to filespec
  1586. X      char *this_file;                 -- will point to matching filename
  1587. X      filespec = parse_command_line(); -- may contain wildcards
  1588. X      FILE *stream;
  1589. X
  1590. X      nextfile (0, filespec, 0);          -- initialize fileset 0
  1591. X      while ((this_file = nextfile(1, (char *) NULL, 0)) != NULL) {
  1592. X         stream = fopen (this_file, "whatever");
  1593. X         if (stream == NULL)
  1594. X            printf ("could not open %s\n", this_file);
  1595. X         else
  1596. X            perform_operations (stream);
  1597. X      }
  1598. X*/
  1599. X
  1600. Xchar *nextfile (what, filespec, fileset)
  1601. Xint what;                        /* whether to initialize or match      */
  1602. Xregister char *filespec;         /* filespec to match if initializing   */
  1603. Xregister int fileset;            /* which set of files                  */
  1604. X{
  1605. X   static struct dta_t new_dta [FMAX+1];     /* our own private dta        */
  1606. X   static int first_time [FMAX+1];
  1607. X   static char pathholder [FMAX+1][PATHSIZE]; /* holds a pathname to return */
  1608. X   static char saved_fspec [FMAX+1][PATHSIZE];/* our own copy of filespec   */
  1609. X   union REGS regs;
  1610. X
  1611. X   assert(fileset >= 0 && fileset <= FMAX);
  1612. X   if (what == 0) {
  1613. X      assert(filespec != NULL);
  1614. X      strcpy (saved_fspec[fileset], filespec);  /* save the filespec */
  1615. X      first_time[fileset] = 1;
  1616. X      return ((char *) NULL);
  1617. X   }
  1618. X
  1619. X   setdta (&new_dta[fileset]);   /* set new dta -- our very own */
  1620. X   assert(what == 1);
  1621. X   assert(filespec == NULL);
  1622. X   assert(first_time[fileset] == 0 || first_time[fileset] == 1);
  1623. X
  1624. X   if (first_time[fileset]) {             /* first time -- initialize etc. */
  1625. X      /* find first matching file */
  1626. X      regs.h.ah = 0x4e;                   /* FindFirst MS-DOS call    */
  1627. X      regs.x.dx = (unsigned int) saved_fspec[fileset]; /* filespec to match */
  1628. X      regs.x.cx = 0;                      /* search attributes       */
  1629. X      intdos (®s, ®s);
  1630. X   } else {
  1631. X      /* find next matching file */
  1632. X      regs.h.ah = 0x4f;                   /* FindNext MS-DOS call     */
  1633. X      intdos (®s, ®s);
  1634. X   }
  1635. X
  1636. X   if (regs.x.carry != 0) {            /* if error status                  */
  1637. X      if (first_time[fileset]) {       /*   if file never matched then     */
  1638. X         first_time[fileset] = 0;
  1639. X         return (saved_fspec[fileset]);/*      return original filespec    */
  1640. X      } else {                         /*   else                           */
  1641. X         first_time[fileset] = 0;      /*                                  */
  1642. X         return ((char *) NULL);         /*      return (NULL) for no more   */
  1643. X      }
  1644. X   } else {                                        /* a file matched */
  1645. X      first_time[fileset] = 0;
  1646. X      /* add path info  */
  1647. X      fcbpath (&new_dta[fileset], saved_fspec[fileset], pathholder[fileset]);
  1648. X      return (pathholder[fileset]);                /* matching path  */
  1649. X   }
  1650. X} /* nextfile */
  1651. X
  1652. X/*******************/
  1653. X/* This function sets the dta to a new dta */
  1654. Xvoid setdta (dta)
  1655. Xstruct dta_t *dta;
  1656. X{
  1657. X   union REGS regs;
  1658. X   regs.h.ah = 0x1a;                /* SetDTA Call       */
  1659. X   regs.x.dx = (unsigned int) dta;  /* new DTA address   */
  1660. X   intdos (®s, ®s);
  1661. X}
  1662. X
  1663. X/*******************/
  1664. X/*
  1665. Xfcbpath() accepts a pointer to the Disk Transfer Area, a character
  1666. Xpointer to a pathname that may contain wildcards, and a character
  1667. Xpointer to a buffer.  It copies into the buffer the path prefix from
  1668. Xthe pathname and the filename prefix from the DTA so that it forms a
  1669. Xcomplete path.
  1670. X*/
  1671. X
  1672. Xvoid fcbpath (dta, old_path, new_path)
  1673. Xstruct dta_t *dta;
  1674. Xchar *old_path;
  1675. Xregister char *new_path;
  1676. X{
  1677. X   register int i;
  1678. X   int length, start_pos;
  1679. X
  1680. X   strcpy(new_path, old_path);               /* copy the whole thing first */
  1681. X   length = strlen(new_path);
  1682. X   i = length - 1;                           /* i points to end of path */
  1683. X   while (i >= 0 && new_path[i] != '/' && new_path[i] != '\\' && new_path[i] != ':')
  1684. X      i--;
  1685. X   /* either we found a "/", "\", or ":", or we reached the beginning of
  1686. X      the name.  In any case, i points to the last character of the
  1687. X      path part. */
  1688. X   start_pos = i + 1;
  1689. X   for (i = 0; i < 13; i++)
  1690. X      new_path[start_pos+i] = dta->fname[i];
  1691. X   new_path[start_pos+13] = '\0';
  1692. X}
  1693. X/* -- END OF nextfile() and related functions -- */
  1694. X
  1695. X/*
  1696. XFor Turbo C, we implement MVFILE as a file copy to avoid wildcard
  1697. Xexpansion finding the same file again after a direct rename.  To
  1698. Xavoid leaving a partially-written destination file, we trap ^C,
  1699. Xand if it occurs, delete the dest file and quickly do just a simple
  1700. Xrename to it.
  1701. X*/
  1702. X
  1703. X#define BLOCKSIZ  16384
  1704. X#include <fcntl.h>
  1705. X#include <sys/stat.h>
  1706. X#include <io.h>
  1707. X#include <signal.h>
  1708. X
  1709. Xvoid handler (int);        /* ^C handler */
  1710. Xchar  *xsrc, *xdest;       /* global for handler() */
  1711. Xvoid (*oldsignal) (int);   /* global for handler() */
  1712. Xint infd, outfd;           /* global for handler() */
  1713. Xint brk_flag;              /* ms-dos break flag status */
  1714. Xint getcbrk (void);
  1715. Xint setcbrk (int);
  1716. X
  1717. Xint MVFILE (src, dest)
  1718. Xchar *src;
  1719. Xchar *dest;
  1720. X{
  1721. X   int retval;
  1722. X   char buf[BLOCKSIZ];
  1723. X
  1724. X   retval = -1;               /* default error return */
  1725. X   xsrc = src;  xdest = dest; /* make visible to handler */
  1726. X
  1727. X   oldsignal = signal (SIGINT, handler);
  1728. X   outfd = open (dest, O_CREAT|O_TRUNC|O_BINARY, S_IREAD|S_IWRITE);
  1729. X   if (outfd == -1)
  1730. X      goto erret;
  1731. X   infd = open (src, O_RDONLY|O_BINARY);
  1732. X   if (infd == -1) {
  1733. X      close (outfd);
  1734. X      goto erret;
  1735. X   }
  1736. X   while ((retval = read (infd, buf, BLOCKSIZ)) > 0) {
  1737. X      if (write (outfd, buf, retval) != retval) {
  1738. X         retval = -1;
  1739. X         goto done;
  1740. X      }
  1741. X   }
  1742. X done: /* retval is zero on normal exit from loop, else nonzero */
  1743. X   close (infd); close (outfd);
  1744. X
  1745. X   if (retval == 0) {
  1746. X      signal (SIGINT, oldsignal);      /* avoid race condition */
  1747. X      unlink (src);
  1748. X      return (retval);
  1749. X   }
  1750. Xerret:
  1751. X   /* if error during read/write, do rename to avoid loss of dest file */
  1752. X   unlink (dest);
  1753. X   retval = rename (src, dest);
  1754. X   signal (SIGINT, oldsignal);
  1755. X   return (retval);
  1756. X}
  1757. X
  1758. Xvoid handler (int sig)
  1759. X{
  1760. X   signal (sig, SIG_IGN);
  1761. X   close (infd);  close (outfd);
  1762. X   unlink (xdest);
  1763. X   rename (xsrc, xdest);
  1764. X   signal (sig, oldsignal);
  1765. X   raise  (sig);                 /* original handler gets signal now */
  1766. X}
  1767. X
  1768. X#include <conio.h>
  1769. Xvoid brktst() { kbhit(); }      /* test for user interrupt */
  1770. X
  1771. Xvoid spec_init()
  1772. X{
  1773. X   brk_flag = getcbrk();
  1774. X   setcbrk (0);
  1775. X}
  1776. X
  1777. Xvoid spec_exit()
  1778. X{
  1779. X   setcbrk (brk_flag);
  1780. X}
  1781. SHAR_EOF
  1782. fi
  1783. echo shar: "extracting 'turboc.cfg'" '(140 characters)'
  1784. if test -f 'turboc.cfg'
  1785. then
  1786.     echo shar: "will not over-write existing file 'turboc.cfg'"
  1787. else
  1788. sed 's/^X//' << \SHAR_EOF > 'turboc.cfg'
  1789. X-wamp
  1790. X-wcln
  1791. X-wuse
  1792. X-wrvl
  1793. X-wsig
  1794. X-wamb
  1795. X-wstv
  1796. X-wpro
  1797. X-wnod
  1798. X-wucp
  1799. X-A
  1800. X-O
  1801. X-Z
  1802. X-k-
  1803. X-d
  1804. X-I\turboc\include
  1805. X-L\turboc\lib
  1806. X-eFLIP
  1807. X-DTURBOC
  1808. X-DLINT
  1809. X-DNDEBUG
  1810. SHAR_EOF
  1811. fi
  1812. exit 0
  1813. #    End of shell archive
  1814.  
  1815.